package com.yunquan.ohana.ui.history.list

import android.app.Application
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableField
import com.google.gson.Gson
import com.yunquan.ohana.BR
import com.yunquan.ohana.R
import com.yunquan.ohana.base.bus.RxBus
import com.yunquan.ohana.base.bus.RxSubscriptions
import com.yunquan.ohana.base.bus.event.SingleLiveEvent
import com.yunquan.ohana.base.ui.BaseViewModel
import com.yunquan.ohana.db.DBFrames
import com.yunquan.ohana.db.DBPhoto
import com.yunquan.ohana.db.DBPhotoFrames
import com.yunquan.ohana.entity.EventEntity
import com.yunquan.ohana.entity.EventType
import com.yunquan.ohana.entity.FileGroupEntity
import com.yunquan.ohana.entity.HistoryEntity
import com.yunquan.ohana.entity.LocalFileEntity
import com.yunquan.ohana.entity.LocalFrameEntity
import com.yunquan.ohana.entity.LocalPhotoFrames
import com.yunquan.ohana.entity.PushDataEntity
import com.yunquan.ohana.entity.UploadResponseEntity
import com.yunquan.ohana.http.BaseHttp
import com.yunquan.ohana.http.observer.BaseObserver
import com.yunquan.ohana.http.transformer.BasePage
import com.yunquan.ohana.http.transformer.CommonTransformer
import com.yunquan.ohana.utils.L
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.Disposable
import me.tatarka.bindingcollectionadapter2.ItemBinding
import okhttp3.RequestBody.Companion.toRequestBody
import java.util.UUID

class HistoryListViewModel(application: Application) : BaseViewModel(application) {

    val ui = SingleLiveEvent<Int>()

    //"Sending", "Completed", "Failed", "Drafts"
    val showType = ObservableField<String>()

    val showNotData = ObservableField(false)

    val items = ObservableArrayList<HistoryItemViewModel>()
    val itemBinding = ItemBinding.of<HistoryItemViewModel>(BR.historyItemViewModel, R.layout.item_history)

    var mCurrentItem: HistoryItemViewModel? = null

    private var page: Int = 1

    fun onRefresh() {
        page = 1
        if (showType.get() == "Completed") {
            getCompletedData()
        } else {
            localData()
        }
    }

    fun onLoadMove() {
        page++
        if (showType.get() == "Completed") {
            getCompletedData()
        } else {
            localData()
        }
    }

    /**
     * 加载本地数据
     */
    private fun localData() {
        val list = if (showType.get() == "Completed") {
            DBPhoto.instance.selectGroupPage(1, page, 30)
        } else if (showType.get() == "Failed") {
            DBPhoto.instance.selectGroupPage(2, page, 30)
        } else if (showType.get() == "Drafts") {
            DBPhoto.instance.selectGroupPage(3, page, 30)
        } else {
            listOf()
        }
        items.clear()
        for (e in list) {
            items.add(HistoryItemViewModel(this, e))
        }
        showNotData.set(items.isEmpty())
        ui.value = 3
    }

    /**
     * 加载服务器完成数据
     */
    private fun getCompletedData() {
        val params = mutableMapOf<String, Any>()
        params["current"] = page
        params["size"] = 30
        val json = Gson().toJson(params)
        val body = json.toRequestBody(BaseHttp.MEDIA_TYPE_JSON)
        BaseHttp.api.getUserTrendsGroupPage(body)
            .compose(CommonTransformer())
            .subscribe(object : BaseObserver<BasePage<HistoryEntity>>() {
                override fun onSuccess(result: BasePage<HistoryEntity>?) {
                    super.onSuccess(result)
                    items.clear()
                    result?.records?.let {
                        for (e in it) {
                            val photos = mutableListOf<LocalFileEntity>()
                            for (p in e.userTrendsList) {
                                val bean = LocalFileEntity(
                                    id = null,
                                    serviceId = p.file.id,
                                    groupId = null,
                                    serviceGroupId = e.groupUid,
                                    content = p.content,
                                    fileName = p.file.fileName,
                                    fileUrl = p.file.fileUrl,
                                    localFileId = null,
                                    localFilePath = null,
                                    localCropId = null,
                                    localCropPath = null,
                                    videoImgUrl = p.file.videoImgUrl,
                                    thumbnail = null,
                                    duration = p.file.lengthInTime,
                                    height = p.file.height,
                                    width = p.file.width,
                                    status = 1,
                                    type = p.type,
                                    createTime = p.createTimeMs.toLong(),
                                )
                                photos.add(bean)
                            }
                            val frames = mutableListOf<LocalFrameEntity>()
                            for (f in e.userDeviceList) {
                                val bean = LocalFrameEntity(
                                    deviceId = f.id,
                                    name = f.name,
                                    location = f.roomLocation,
                                    online = if (f.online) 1 else 0,
                                    receipt = f.receipt
                                )
                                frames.add(bean)
                            }
                            val bean = FileGroupEntity(
                                groupId = null,
                                serviceGroupId = e.groupUid,
                                photos = photos,
                                frames = frames,
                            )
                            items.add(HistoryItemViewModel(this@HistoryListViewModel, bean))
                        }
                    }
                }

                override fun onComplete() {
                    super.onComplete()
                    showNotData.set(items.isEmpty())
                    ui.value = 3
                }
            })
    }

    override fun onEvent(event: EventEntity) {
        super.onEvent(event)
        when (event.type) {
            EventType.UPLOAD_FILE -> {
                // 收到发送通知，更新UI显示
                if (showType.get() == "Sending") {
                    val data = event.data as FileGroupEntity
                    items.add(0, HistoryItemViewModel(this, data))
                    showNotData.set(items.isEmpty())
                    ui.value = 5
                }
            }

            EventType.UPLOAD_FILE_PROGRESS -> {
                // 进度更新
                if (showType.get() == "Sending") {
                    val data = event.data as UploadResponseEntity
                    val item = items.find { it.data?.groupId == data.groupId }
                    item?.setProgress(data.progress)
                }
            }

            EventType.UPLOAD_SUCCESS -> {
                // 发送成功
                val data = event.data as FileGroupEntity
                if (showType.get() == "Sending") {
                    val item = items.find { it.data?.groupId == data.groupId }
                    item?.setProgress(100)
                    items.remove(item)
                    showNotData.set(items.isEmpty())
                } else if (showType.get() == "Completed") {
                    items.add(0, HistoryItemViewModel(this, data))
                    showNotData.set(items.isEmpty())
                    ui.value = 5
                }
            }

            EventType.UPLOAD_FAILED -> {
                // 发送失败
                val data = event.data as FileGroupEntity
                if (showType.get() == "Sending") {
                    val item = items.find { it.data?.groupId == data.groupId }
                    item?.setProgress(100)
                    items.remove(item)
                    showNotData.set(items.isEmpty())
                } else if (showType.get() == "Failed") {
                    items.add(0, HistoryItemViewModel(this, data))
                    showNotData.set(items.isEmpty())
                    ui.value = 5
                }
            }

            EventType.MOVE_TO_DRAFTS -> {
                // 转到草稿
                if (showType.get() == "Drafts") {
                    val data = event.data as FileGroupEntity
                    items.add(0, HistoryItemViewModel(this, data))
                    showNotData.set(items.isEmpty())
                    ui.value = 5
                }
            }

            EventType.RESEND_DELETE -> {
                // 重新发送，删除记录
                val groupId = event.data as String
                if (showType.get() == "Drafts" || showType.get() == "Failed") {
                    DBPhotoFrames.instance.delete(groupId)
                    DBPhoto.instance.delete(groupId)
                    val item = items.find { it.data?.groupId == groupId }
                    items.remove(item)
                    showNotData.set(items.isEmpty())
                }
            }

            EventType.UPDATE_FRAMES_RECEIVE -> {
                // 接收状态改变
                if (showType.get() == "Completed") {
                    val data = event.data as PushDataEntity?
                    if (data != null) {
                        try {
                            val item = items.find { it.data?.serviceGroupId == data.groupUid }
                            if (item != null) {
                                val index = item.data?.frames?.indexOfFirst { it.deviceId == data.deviceId } ?: -1
                                if (index >= 0) {
                                    item.data!!.frames[index].receipt = true

                                    val framesStatus = try {
                                        item.data!!.frames.first { it.receipt == false }
                                    } catch (_: Exception) {
                                        null
                                    }
                                    item.showLookStatus.set(framesStatus != null)
                                }
                            }
                        } catch (_: Exception) {
                        }
                    }
                }
            }

            EventType.FRESH_HISTORY_COMPLETED -> {
                // 刷新完成历史
                if (showType.get() == "Completed") {
                    getCompletedData()
                }
            }

            else -> {}
        }
    }

    /**
     * 撤销
     */
    fun onRevoke(item: HistoryItemViewModel) {
        mCurrentItem = item
        ui.value = 0
    }

    /**
     * 删除
     */
    fun onDelete(item: HistoryItemViewModel) {
        mCurrentItem = item
        ui.value = 1
    }

    /**
     * 发送/重发
     */
    fun onResend(item: HistoryItemViewModel) {
        mCurrentItem = item
        ui.value = 2
    }

    /**
     * 撤回、删除文件
     */
    fun deleteAlbum(isSave: Boolean) {
        if (mCurrentItem?.data == null || (mCurrentItem?.data?.groupId == null && mCurrentItem?.data?.serviceGroupId == null)) {
            return
        }
        val data = mCurrentItem!!.data!!
        val serviceGroupId = if (data.serviceGroupId != null) data.serviceGroupId else data.photos.first().serviceGroupId
        if (serviceGroupId == null) {
            RxBus.getDefault().post(EventEntity(EventType.REVOKE_SEND_POST, data.groupId))
            if (isSave) {
                DBPhoto.instance.updateStatus(data.groupId!!, 3)
                RxBus.getDefault().post(EventEntity(EventType.MOVE_TO_DRAFTS, data))
            } else {
                DBPhotoFrames.instance.delete(data.groupId!!)
                DBPhoto.instance.delete(data.groupId!!)
                RxBus.getDefault().post(EventEntity(EventType.RESEND_DELETE))
            }
            items.remove(mCurrentItem)
            mCurrentItem = null
            return
        }
        val params = mutableMapOf<String, String>()
        params["groupUid"] = serviceGroupId
        val json = Gson().toJson(params)
        val body = json.toRequestBody(BaseHttp.MEDIA_TYPE_JSON)
        BaseHttp.api.deleteGroupUserTrends(body)
            .compose(CommonTransformer())
            .subscribe(object : BaseObserver<Boolean>() {
                override fun onSubscribe(d: Disposable) {
                    super.onSubscribe(d)
                    if (data.groupId != null) {
                        if (isSave) {
                            DBPhoto.instance.updateStatus(data.groupId!!, 3)
                            RxBus.getDefault().post(EventEntity(EventType.MOVE_TO_DRAFTS, data))
                        } else {
                            DBPhotoFrames.instance.delete(data.groupId!!)
                            DBPhoto.instance.delete(data.groupId!!)
                        }
                    } else {
                        if (isSave) {
                            val groupId = UUID.randomUUID().toString()
                            for (e in data.photos) {
                                e.groupId = groupId
                                e.status = 3
                                DBPhoto.instance.insert(e)
                            }
                            for (e in data.frames) {
                                val bean = LocalPhotoFrames(
                                    id = null,
                                    groupId = groupId,
                                    framesId = e.deviceId,
                                    status = 0,
                                )
                                DBPhotoFrames.instance.insert(bean)
                            }
                            val photosFrames = DBPhotoFrames.instance.selectByGroupId(groupId)
                            val framesIds = photosFrames.map { it.framesId!! }.toList()
                            val localFrames = DBFrames.instance.selectInDeviceIds(framesIds)
                            val localPhotos = DBPhoto.instance.selectByGroupId(groupId)
                            val localData = FileGroupEntity(
                                groupId = groupId,
                                serviceGroupId = null,
                                photos = localPhotos,
                                frames = localFrames,
                            )
                            RxBus.getDefault().post(EventEntity(EventType.MOVE_TO_DRAFTS, localData))
                        }
                    }
                    items.remove(mCurrentItem)
                    mCurrentItem = null
                }

                override fun onComplete() {
                    super.onComplete()
                    showNotData.set(items.isEmpty())
                }
            })

    }
}